import selectors
import socket
import threading
import webob

html_content = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        This is a test page!
    </div>
</body>
</html>
"""

class WebServer:
    def __init__(self,ip='127.0.0.1',port=9999):
        self.addr = ip,port
        self.sock = socket.socket()
        self.sock.setblocking(False)
        self.event = threading.Event()
        self.selector = selectors.DefaultSelector()


    def start(self):
        self.sock.bind(self.addr)
        self.sock.listen()
        key = self.selector.register(self.sock,selectors.EVENT_READ,self.accept)
        threading.Thread(target=self.select,name='select').start()

    def select(self):
        with self.selector:
            while not self.event.is_set():
                readyeventset = self.selector.select(1)
                #print(readyeventset)
                for key,mask in readyeventset:
                    key.data(key.fileobj,mask)

    def accept(self,server:socket.socket,mask):
        conn,raddr = server.accept()
        conn.setblocking(False)
        key = self.selector.register(conn,selectors.EVENT_READ,self.recv)


    def recv(self,conn:socket.socket,mask):
        with conn:
            try:
                data = conn.recv(1024).strip()
                request = webob.Request.from_bytes(data)
                print(request.url)
                response = webob.Response(html_content,status=200)
                response.headers.add('server','MyServer')
                fline = 'HTTP/1.1 {}'.format(response.status)
                print(response.headerlist)
                headers = "\r\n".join(
                    [fline] + ["{}: {}".format(k,v) for k,v in response.headerlist] + ["",""]
                )
                body = response.body
                print(type(headers),type(body))
                content = headers.encode() +body
                conn.send(content)
            finally:
                self.selector.unregister(conn)

    def stop(self):
        self.event.set()


if __name__ == '__main__':
    cs = WebServer()
    cs.start()
    while True:
        cmd = input('~$').strip()
        if cmd == 'quit':
            cs.stop()
            break